const fs = require('fs');
const path = require('path');
const cheerio = require('cheerio');

// 日志记录函数
function logMessage(message) {
    console.log(`[${new Date().toISOString()}] ${message}`);
}

function logError(message, error = null) {
    const errorMessage = `[${new Date().toISOString()}] ERROR: ${message}${error ? ' - ' + error.message : ''}`;
    console.error(errorMessage);
    
    // 写入错误日志文件
    try {
        fs.appendFileSync('error.log', errorMessage + '\n');
    } catch (writeError) {
        console.error('无法写入错误日志文件:', writeError.message);
    }
}

// 标准化时间格式
function normalizeTime(timeStr) {
    if (!timeStr) return '';
    
    // 清理时间字符串
    const cleanTime = timeStr.trim().replace(/&nbsp;/g, ' ');
    
    // 检查是否已经是标准格式 YYYY-MM-DD HH:MM:SS
    const standardFormat = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
    if (standardFormat.test(cleanTime)) {
        return cleanTime;
    }
    
    // 尝试解析其他常见格式
    try {
        const date = new Date(cleanTime);
        if (!isNaN(date.getTime())) {
            return date.toISOString().slice(0, 19).replace('T', ' ');
        }
    } catch (error) {
        logError(`时间格式解析失败: ${timeStr}`, error);
    }
    
    // 如果无法解析，返回原始值
    return cleanTime;
}

// 清理文本内容
function cleanText(text) {
    if (!text) return '';
    
    return text
        .replace(/&nbsp;/g, ' ')
        .replace(/\s+/g, ' ')
        .trim();
}

// 提取语音转换文本
function extractVoiceText($, element) {
    const voiceTexts = [];
    
    // 查找语音内容标记
    const voiceElements = $(element).find('span').filter((i, el) => {
        const text = $(el).text();
        return text.includes('[🎵语音内容]') || text.includes('语音内容');
    });
    
    voiceElements.each((i, el) => {
        const text = $(el).text();
        // 提取语音内容，只保留转换后的文本
        const voiceMatch = text.match(/\[🎵语音内容\]:\s*(.+?)(?:\s*$)/);
        if (voiceMatch) {
            voiceTexts.push(voiceMatch[1].trim());
        }
    });
    
    return voiceTexts;
}

// 解析单个HTML文件
function parseHtmlFile(filePath) {
    try {
        const htmlContent = fs.readFileSync(filePath, 'utf8');
        const $ = cheerio.load(htmlContent);
        const chatRecords = [];
        
        // 查找所有聊天消息容器
        const contentDivs = $('.content');
        let currentMessage = null;
        
        contentDivs.each((index, element) => {
            const $element = $(element);
            
            // 查找发送者信息
            const senderElement = $element.find('.SenderNameMe, .SenderNameYou');
            const timeElement = $element.find('.MsgTime');
            const historyElement = $element.find('.MsgHistory');
            
            // 如果找到发送者和时间信息，这是一条新消息的开始
            if (senderElement.length > 0 && timeElement.length > 0) {
                // 保存之前的消息（如果存在）
                if (currentMessage && currentMessage.content.trim()) {
                    chatRecords.push(currentMessage);
                }
                
                // 创建新消息
                currentMessage = {
                    sender: cleanText(senderElement.text()),
                    send_time: normalizeTime(timeElement.text()),
                    content: '',
                    type: 'txt' // 默认为文本消息
                };
            }
            
            // 检查是否有语音转换文本
            const voiceTexts = extractVoiceText($, element);
            if (voiceTexts.length > 0 && currentMessage) {
                // 设置为语音消息类型，只保留转换后的文本
                currentMessage.type = 'voice';
                voiceTexts.forEach(voiceText => {
                    if (currentMessage.content) {
                        currentMessage.content += ' ';
                    }
                    currentMessage.content += voiceText;
                });
            } else {
                // 如果找到普通消息内容且不是语音消息
                if (historyElement.length > 0) {
                    const textContent = cleanText(historyElement.text());
                    if (textContent && currentMessage) {
                        if (currentMessage.content) {
                            currentMessage.content += ' ';
                        }
                        currentMessage.content += textContent;
                    }
                }
            }
        });
        
        // 保存最后一条消息
        if (currentMessage && currentMessage.content.trim()) {
            chatRecords.push(currentMessage);
        }
        
        // 按时间排序
        chatRecords.sort((a, b) => {
            const timeA = new Date(a.send_time);
            const timeB = new Date(b.send_time);
            if (isNaN(timeA.getTime()) || isNaN(timeB.getTime())) {
                return 0; // 如果时间无法解析，保持原顺序
            }
            return timeA - timeB;
        });
        
        return chatRecords;
        
    } catch (error) {
        logError(`解析HTML文件失败: ${filePath}`, error);
        return [];
    }
}

// 递归查找所有msg_txt.html文件
function findHtmlFiles(dir) {
    const htmlFiles = [];
    
    try {
        const items = fs.readdirSync(dir);
        
        for (const item of items) {
            const fullPath = path.join(dir, item);
            const stat = fs.statSync(fullPath);
            
            if (stat.isDirectory()) {
                // 递归搜索子目录
                htmlFiles.push(...findHtmlFiles(fullPath));
            } else if (item === 'msg_txt.html') {
                htmlFiles.push(fullPath);
            }
        }
    } catch (error) {
        logError(`读取目录失败: ${dir}`, error);
    }
    
    return htmlFiles;
}

// 主处理函数
function main() {
    // 解析命令行参数
    const args = process.argv.slice(2);
    const overwrite = args.includes('--overwrite') || args.includes('-o');
    
    logMessage('开始提取聊天记录...');
    if (overwrite) {
        logMessage('覆盖模式：将覆盖现有的chat.json文件');
    } else {
        logMessage('跳过模式：将跳过已存在的chat.json文件');
    }
    
    const dataDir = path.join(__dirname, 'data');
    
    // 检查data目录是否存在
    if (!fs.existsSync(dataDir)) {
        logError(`数据目录不存在: ${dataDir}`);
        return;
    }
    
    // 查找所有HTML文件
    const htmlFiles = findHtmlFiles(dataDir);
    logMessage(`找到 ${htmlFiles.length} 个msg_txt.html文件`);
    
    if (htmlFiles.length === 0) {
        logMessage('未找到任何msg_txt.html文件');
        return;
    }
    
    // 处理每个HTML文件
    for (const htmlFile of htmlFiles) {
        // 生成输出文件路径（在HTML文件同目录下）
        const outputDir = path.dirname(htmlFile);
        const outputFile = path.join(outputDir, 'chat.json');
        
        // 检查是否需要跳过已存在的文件
        if (!overwrite && fs.existsSync(outputFile)) {
            logMessage(`⏭️  跳过已存在的文件: ${outputFile}`);
            continue;
        }
        
        logMessage(`正在处理: ${htmlFile}`);
        
        const chatRecords = parseHtmlFile(htmlFile);
        
        if (chatRecords.length > 0) {
            try {
                // 写入JSON文件
                fs.writeFileSync(outputFile, JSON.stringify(chatRecords, null, 2), 'utf8');
                logMessage(`✅ 成功提取 ${chatRecords.length} 条记录，保存到: ${outputFile}`);
            } catch (error) {
                logError(`保存JSON文件失败: ${outputFile}`, error);
            }
        } else {
            logMessage(`⚠️  未从文件中提取到任何记录: ${htmlFile}`);
        }
    }
    
    logMessage('聊天记录提取完成！');
}

// 运行主函数
if (require.main === module) {
    main();
}

module.exports = {
    parseHtmlFile,
    findHtmlFiles,
    normalizeTime,
    cleanText,
    extractVoiceText
};
